package simonxianyu.boot.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 数据访问服务抽象类
 * @param <REPO>
 * @param <T>
 * @param <ID>
 */
abstract public class BaseJpaDbSvc<REPO extends JpaRepository<T, ID>,T,ID> {
  @Autowired
  protected REPO repo;

  public List<T> findAll() {
    return repo.findAll();
  }

  public Page<T> findPaged(Pageable pr) {
    return repo.findAll(pr);
  }

  public Optional<T> get(ID id) {
    return repo.findById(id);
  }

  @Transactional
  public ID saveOrUpdate(T m) {
    if (m == null) {
      return null;
    }
    ID key = extractId(m);
    T exist = null;
    if (null == key) {
      exist = m;
    } else {
      Optional<T> oe = repo.findById(key);
      if (oe.isPresent()) {
        exist = oe.get();
        doMerge(exist, m);
      } else {
        exist = m;
      }
    }
    T saved = repo.save(exist);
    return extractId(saved);
  }

  protected abstract void doMerge(T exist, T m);

  abstract protected ID extractId(T m);

  protected void doDeleteById(ID id) {
    repo.deleteById(id);
  }
}
